home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 6 / The Arsenal Files 6 (Arsenal Computer).ISO / prg_casm / jlvesa11.zip / JLVESA21.ASM < prev    next >
Assembly Source File  |  1995-11-14  |  8KB  |  383 lines

  1. ; This routine is part of VESA SVGA -library
  2. ;
  3. ; Copyright 1994 Johannes Lehtinen
  4. ; All rights reserved
  5.  
  6. model large,c
  7. p386
  8.  
  9. include "jlvesads.asm"
  10.  
  11. extrn vesa_repos_w:far
  12.  
  13. segment jlvesa21_TEXT USE16 'CODE'
  14. assume cs:jlvesa21_TEXT
  15.  
  16. ; void JVImage_DrawLimited(JLSWord x, JLSWord y, JLUWord width, JLUWord height,
  17. ;                          void *image, JLSWord lx, JLSWord ly, JLUWord lwidth,
  18. ;                          JLUWord lheight)
  19. ;
  20. ; Puts image to screen. Output is done only inside given limits.
  21. ;
  22. ; lx = [ss:bp+18]
  23.  
  24. ; Some information
  25.  
  26. bl_linesleft   dw ?  ; Lines left to draw
  27. bl_repolines   dw ?  ; Lines before next reposition
  28. bl_overflines  dw ?  ; Lines before next overflow
  29. bl_left        dw ?  ; Pixels outside the left border
  30. bl_up          dw ?  ; Pixels outside the upper border
  31. bl_right       dw ?  ; Pixels outside the right border
  32. bl_width       dw ?  ; Pixels on screen horizontally
  33.  
  34. proc JVImage_DrawLimited far
  35.    public JVImage_DrawLimited
  36.  
  37.    push  bp
  38.    mov   bp,sp
  39.    push  si
  40.    push  di
  41.    push  ds
  42.    push  es
  43.    push  fs
  44.  
  45.    mov   ax,JLVesa_Data
  46.    mov   fs,ax
  47.  
  48.    mov   [cs:bl_left],0
  49.    mov   [cs:bl_up],0
  50.    mov   [cs:bl_right],0
  51.  
  52.    ; Make sure the block is on limited area
  53.    ; Check that x>=lx
  54.  
  55.    mov   ax,[ss:bp+18]
  56.    cmp   [ss:bp+6],ax
  57.    jge   short x_not_below
  58.  
  59.    ; X is less than lx
  60.  
  61.    sub   ax,[ss:bp+6]
  62.    mov   [cs:bl_left],ax
  63.  
  64.    ; Check that y>=ly
  65.  
  66. x_not_below:
  67.    mov   ax,[ss:bp+20]
  68.    cmp   [word ptr ss:bp+8],ax
  69.    jge   short y_not_below
  70.  
  71.    ; Y is less than 0
  72.  
  73.    sub   ax,[ss:bp+8]
  74.    mov   [cs:bl_up],ax
  75.  
  76.    ; Calculate pixels on limited area at this point
  77.  
  78. y_not_below:
  79.    mov   ax,[ss:bp+10]
  80.    sub   ax,[cs:bl_left]
  81.    mov   [cs:bl_width],ax
  82.    mov   ax,[ss:bp+12]
  83.    sub   ax,[cs:bl_up]
  84.    mov   [cs:bl_linesleft],ax
  85.  
  86.    mov   ax,[ss:bp+6]
  87.    add   ax,[ss:bp+10]
  88.    sub   ax,[ss:bp+18]
  89.    cmp   [ss:bp+22],ax
  90.    jg    short width_not_above
  91.  
  92.    ; Wider than limited area
  93.  
  94.    sub   ax,[ss:bp+22]
  95.    mov   [cs:bl_right],ax
  96.    mov   ax,[ss:bp+10]
  97.    sub   ax,[cs:bl_left]
  98.    sub   ax,[cs:bl_right]
  99.    mov   [cs:bl_width],ax
  100.  
  101. width_not_above:
  102.    mov   ax,[ss:bp+8]
  103.    add   ax,[ss:bp+12]
  104.    sub   ax,[ss:bp+20]
  105.    cmp   [ss:bp+24],ax
  106.    jg    short height_not_above
  107.  
  108.    ; Heigher than limited area
  109.  
  110.    sub   ax,[ss:bp+24]
  111.    mov   bx,ax
  112.    mov   ax,[ss:bp+12]
  113.    sub   ax,[cs:bl_up]
  114.    sub   ax,bx
  115.    mov   [cs:bl_linesleft],ax
  116.  
  117.    ; Check that width or height is not negative
  118.  
  119. height_not_above:
  120.    cmp   [cs:bl_width],0
  121.    jle   end_of_block
  122.    cmp   [cs:bl_linesleft],0
  123.    jle   end_of_block
  124.  
  125.    ; Calculate absolute address of starting point
  126.  
  127.    xor   eax,eax              ; Calculate address of start of line
  128.    xor   ebx,ebx
  129.    mov   ax,[ss:bp+8]
  130.    add   ax,[cs:bl_up]
  131.    mov   bx,[fs:LWidth]
  132.    mul   ebx
  133.    mov   bx,[ss:bp+6]         ; Calculate address of starting point
  134.    add   bx,[cs:bl_left]
  135.    add   eax,ebx
  136.    add   eax,[fs:AStart]      ; Calculate address if scrolled
  137.    mov   edx,eax
  138.  
  139.    ; Initialize registers used
  140.  
  141.    mov   ax,[fs:WWSeg]
  142.    mov   es,ax
  143.    cld                        ; Direction forward
  144.  
  145.    ; Reposition window if necessary
  146.  
  147.    cmp   [fs:WAStart],edx
  148.    jbe   short not_bef_win
  149.    call  far vesa_repos_w
  150.    jmp   short go_drawing
  151.  
  152. not_bef_win:
  153.    mov   eax,[fs:WAStart]
  154.    add   eax,[fs:WSize]
  155.    cmp   edx,eax
  156.    jb    short go_drawing
  157.    call  far vesa_repos_w
  158.  
  159.    ; Calculate current offset
  160.  
  161. go_drawing:
  162.    mov   edi,edx
  163.    sub   edi,[fs:WAStart]
  164.  
  165.    ; Read DS:SI
  166.  
  167.    xor   eax,eax
  168.    mov   ax,[cs:bl_up]
  169.    xor   ebx,ebx
  170.    mov   bx,[ss:bp+10]        ; EBX is width of image
  171.    push  edx
  172.    mul   ebx
  173.    pop   edx
  174.    mov   bx,[cs:bl_left]
  175.    add   eax,ebx              ; EAX is number of bytes to add to SI
  176.  
  177.    xor   esi,esi
  178.    mov   si,[ss:bp+14]        ; Read SI and make addition
  179.    add   esi,eax
  180.  
  181.    mov   ebx,esi
  182.    shr   ebx,4
  183.    and   esi,0fH
  184.    mov   ax,[ss:bp+16]        ; Read DS and make addition
  185.    add   ax,bx
  186.    mov   ds,ax
  187.  
  188.    ; Drawing loop
  189.  
  190.    ; First calculate, how many lines can be drawn without address overflow.
  191.    ; Check both ES:DI and DS:SI.
  192.  
  193.    ; First check how many lines before window reposition
  194.  
  195. draw_loop:
  196.    cmp   [cs:bl_linesleft],0
  197.    je    end_of_block
  198.  
  199.    mov   eax,[fs:WAStart]
  200.    add   eax,[fs:WSize]
  201.    dec   eax
  202.    sub   eax,edx
  203.    xor   ebx,ebx
  204.    mov   bx,[fs:LWidth]
  205.    push  edx
  206.    xor   edx,edx
  207.    div   ebx
  208.    pop   edx
  209.  
  210.    cmp   [cs:bl_linesleft],ax ; Check if fewer lines left than possible to draw on the page
  211.    jae   short jump_0
  212.    mov   ax,[cs:bl_linesleft]
  213.  
  214. jump_0:
  215.    mov   [cs:bl_repolines],ax
  216.  
  217.    ; Then check how many lines before DS:SI overflow
  218.  
  219.    mov   eax,10000H
  220.    sub   eax,esi
  221.    push  edx
  222.    xor   edx,edx
  223.    xor   ebx,ebx
  224.    mov   bx,[fs:LWidth]
  225.    div   ebx
  226.    pop   edx
  227.  
  228.    cmp   [cs:bl_linesleft],ax ; Check if fewer lines left than possible to draw before overflow
  229.    jae   short jump_1
  230.    mov   ax,[cs:bl_linesleft]
  231.  
  232. jump_1:
  233.    mov   [cs:bl_overflines],ax
  234.  
  235.    ; Start drawing as many lines as possible before
  236.    ; First check if normal lines can be drawn next at all
  237.  
  238. draw_line:
  239.    cmp   [cs:bl_overflines],0
  240.    je    overf_check
  241.  
  242.    cmp   [cs:bl_repolines],0
  243.    je    short special_line
  244.  
  245.    mov   cx,[cs:bl_width]     ; Width of the block
  246.    cmp   cx,3
  247.    jb    short jump_4
  248.  
  249.    test  di,1                 ; Check if need to write one byte
  250.    jz    short jump_2
  251.    movsb
  252.    dec   cx
  253.  
  254. jump_2:
  255.    test  di,2                 ; Check if need to write two bytes
  256.    jz    short jump_3
  257.    movsw
  258.    sub   cx,2
  259.  
  260. jump_3:
  261.    mov   bx,cx                ; Write four bytes at time
  262.    shr   cx,2
  263.    jz    short jump_4
  264.  
  265.    rep   movsd
  266.    mov   cx,bx
  267.  
  268. jump_4:
  269.    test  cx,2
  270.    jz    short jump_5
  271.    movsw
  272.  
  273. jump_5:
  274.    test  cx,1
  275.    jz    short jump_6
  276.    movsb
  277.  
  278. jump_6:
  279.    add   di,[fs:LWidth]       ; Move to the start of next line
  280.    sub   di,[cs:bl_width]
  281.  
  282.    xor   ecx,ecx
  283.    mov   cx,[fs:LWidth]
  284.    add   edx,ecx
  285.    add   si,[cs:bl_right]
  286.    add   si,[cs:bl_left]
  287.  
  288.    dec   [cs:bl_repolines]
  289.    dec   [cs:bl_overflines]
  290.    dec   [cs:bl_linesleft]
  291.    jmp   short draw_line
  292.  
  293.    ; Draw line, which is between two pages
  294.  
  295. special_line:
  296.    mov   ecx,[fs:WAStart]     ; Calculate how line is divided
  297.    add   ecx,[fs:WSize]
  298.    sub   ecx,edx
  299.    cmp   [cs:bl_width],cx
  300.    jbe   short line_on_current   ; Line on current page
  301.  
  302.    ; Line is divided on both pages
  303.  
  304.    mov   bx,[cs:bl_width]     ; BX = length of the line on next page
  305.    sub   bx,cx
  306.    rep   movsb                ; Draw line on current page
  307.  
  308.    xor   ecx,ecx
  309.    mov   cx,[fs:LWidth]
  310.    add   edx,ecx              ; Switch on next page
  311.    call  far vesa_repos_w
  312.    mov   edi,edx              ; Calculate new DI
  313.    xor   ecx,ecx
  314.    mov   cx,[fs:LWidth]
  315.    sub   edi,ecx
  316.    xor   ecx,ecx
  317.    mov   cx,[cs:bl_width]
  318.    add   edi,ecx
  319.    sub   edi,[fs:WAStart]
  320.    sub   di,bx
  321.  
  322.    mov   cx,bx                ; Draw line on next page
  323.    rep   movsb
  324.  
  325.    add   di,[fs:LWidth]       ; Move on the next line
  326.    sub   di,[cs:bl_width]
  327.  
  328.    add   si,[cs:bl_right]
  329.    add   si,[cs:bl_left]
  330.  
  331.    dec   [cs:bl_linesleft]
  332.    jnz   draw_loop
  333.    jmp   short end_of_block
  334.  
  335.    ; Line is on current page
  336.  
  337. line_on_current:
  338.    mov   cx,[cs:bl_width]     ; Draw line on this page
  339.    rep   movsb
  340.  
  341.    xor   ecx,ecx
  342.    mov   cx,[fs:LWidth]
  343.    add   edx,ecx
  344.    call  far vesa_repos_w
  345.    mov   edi,edx              ; Move to start of next line
  346.    sub   edi,[fs:WAStart]
  347.  
  348.    add   si,[cs:bl_right]
  349.    add   si,[cs:bl_left]
  350.  
  351.    dec   [cs:bl_linesleft]
  352.    jnz   draw_loop
  353.    jmp   short end_of_block
  354.  
  355.    ; Handle DS:SI overflow
  356.  
  357. overf_check:
  358.    mov   ax,si
  359.    shr   ax,4
  360.    mov   bx,ds
  361.    add   ax,bx
  362.    mov   ds,ax
  363.    and   si,0fH
  364.    jmp   draw_loop
  365.  
  366.    ; End drawing
  367.  
  368. end_of_block:
  369.    pop   fs
  370.    pop   es
  371.    pop   ds
  372.    pop   di
  373.    pop   si
  374.    pop   bp
  375.    retf
  376.  
  377. endp JVImage_DrawLimited
  378.  
  379. ends
  380.  
  381. end
  382.  
  383.